home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util4 / bytmrk20.lha / nbench0.c < prev    next >
C/C++ Source or Header  |  1995-11-03  |  31KB  |  1,032 lines

  1.  
  2. /*
  3. ** nbench0.c
  4. */
  5.  
  6. /*******************************************
  7. **             BYTEmark (tm)              **
  8. ** BYTE MAGAZINE'S NATIVE MODE BENCHMARKS **
  9. **           FOR CPU/FPU                  **
  10. **             ver 2.0                    **
  11. **       Rick Grehan, BYTE Magazine       **
  12. ********************************************
  13. ** NOTE: These benchmarks do NOT check for the presence
  14. ** of an FPU.  You have to find that out manually.
  15. **
  16. ** REVISION HISTORY FOR BENCHMARKS
  17. **  9/94 -- First beta. --RG
  18. **  12/94 -- Bug discovered in some of the integer routines
  19. **    (IDEA, Huffman,...).  Routines were not accurately counting
  20. **    the number of loops.  Fixed. --RG (Thanks to Steve A.)
  21. **  12/94 -- Added routines to calculate and display index
  22. **    values. Indexes based on DELL XPS 90 (90 MHz Pentium).
  23. **  1/95 -- Added Mac time manager routines for more accurate
  24. **    timing on Macintosh (said to be good to 20 usecs) -- RG
  25. **  1/95 -- Re-did all the #defines so they made more
  26. **    sense.  See NMGLOBAL.H -- RG
  27. **  3/95 -- Fixed memory leak in LU decomposition.  Did not
  28. **    invalidate previous results, just made it easier to run.--RG
  29. **  3/95 -- Added TOOLHELP.DLL timing routine to Windows timer. --RG
  30. */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <ctype.h>
  35. #include <string.h>
  36. #include <time.h>
  37. #include <math.h>
  38. #include "nmglobal.h"
  39. #include "nbench0.h"
  40.  
  41. /*************
  42. **** main ****
  43. *************/
  44. #ifdef MAC
  45. void main(void)
  46. #else
  47. void main(int argc, char **argv)
  48. #endif
  49. {
  50. int i;                  /* Index */
  51. time_t time_and_date;   /* Self-explanatory */
  52. struct tm *loctime;
  53. double bmean;           /* Benchmark mean */
  54. double bstdev;          /* Benchmark stdev */
  55. double intindex;        /* Integer index */
  56. double fpindex;            /* Floating-point index */
  57. ulong bnumrun;          /* # of runs */
  58.  
  59. #ifdef MAC
  60.         MaxApplZone();
  61. #endif
  62.                 
  63. #ifdef MACTIMEMGR
  64. /* Set up high res timer */
  65. MacHSTdelay=600*1000*1000;      /* Delay is 10 minutes */
  66.  
  67. memset((char *)&myTMTask,0,sizeof(TMTask));
  68.  
  69. /* Prime and remove the task, calculating overhead */
  70. PrimeTime((QElemPtr)&myTMTask,-MacHSTdelay);
  71. RmvTime((QElemPtr)&myTMTask);
  72. MacHSTohead=MacHSTdelay+myTMTask.tmCount;
  73. #endif
  74.  
  75. #ifdef WIN31TIMER
  76. /* Set up the size of the timer info structure */
  77. win31tinfo.dwSize=(DWORD)sizeof(TIMERINFO);
  78. /* Load library */
  79. if((hThlp=LoadLibrary("TOOLHELP.DLL"))<32)
  80. {    printf("Error loading TOOLHELP\n");
  81.     exit(0);
  82. }
  83. if(!(lpfn=GetProcAddress(hThlp,"TimerCount")))
  84. {    printf("TOOLHELP error\n");
  85.     exit(0);
  86. }
  87. #endif
  88.  
  89. /*
  90. ** Set global parameters to default.
  91. */
  92. global_min_ticks=MINIMUM_TICKS;
  93. global_min_seconds=MINIMUM_SECONDS;
  94. global_allstats=0;
  95. global_custrun=0;
  96. write_to_file=0;
  97. intindex=(double)1.0;
  98. fpindex=(double)1.0;
  99.  
  100. /*
  101. ** We presume all tests will be run unless told
  102. ** otherwise
  103. */
  104. for(i=0;i<NUMTESTS;i++)
  105.         tests_to_do[i]=1;
  106.  
  107. /*
  108. ** Initialize test data structures to default
  109. ** values.
  110. */
  111. set_request_secs();     /* Set all request_secs fields */
  112. global_numsortstruct.adjust=0;
  113. global_numsortstruct.arraysize=NUMARRAYSIZE;
  114.  
  115. global_strsortstruct.adjust=0;
  116. global_strsortstruct.arraysize=STRINGARRAYSIZE;
  117.  
  118. global_bitopstruct.adjust=0;
  119. global_bitopstruct.bitfieldarraysize=BITFARRAYSIZE;
  120.  
  121. global_emfloatstruct.adjust=0;
  122. global_emfloatstruct.arraysize=EMFARRAYSIZE;
  123.  
  124. global_fourierstruct.adjust=0;
  125.  
  126. global_assignstruct.adjust=0;
  127.  
  128. global_ideastruct.adjust=0;
  129. global_ideastruct.arraysize=IDEAARRAYSIZE;
  130.  
  131. global_huffstruct.adjust=0;
  132. global_huffstruct.arraysize=HUFFARRAYSIZE;
  133.  
  134. global_nnetstruct.adjust=0;
  135.  
  136. global_lustruct.adjust=0;
  137.  
  138. /*
  139. ** For Macintosh -- read the command line.
  140. */
  141. #ifdef MAC
  142. UCommandLine();
  143. #endif
  144.  
  145. /*
  146. ** Handle any command-line arguments.
  147. */
  148. if(argc>1)
  149.         for(i=1;i<argc;i++)
  150.                 if(parse_arg(argv[i])==-1)
  151.                 {       display_help(argv[0]);
  152.                         exit(0);
  153.                 }
  154. /*
  155. ** Output header
  156. */
  157. output_string("BBBBBB   YYY   Y  TTTTTTT  EEEEEEE\n");
  158. output_string("BBB   B  YYY   Y    TTT    EEE\n");
  159. output_string("BBB   B  YYY   Y    TTT    EEE\n");
  160. output_string("BBBBBB    YYY Y     TTT    EEEEEEE\n");
  161. output_string("BBB   B    YYY      TTT    EEE\n");
  162. output_string("BBB   B    YYY      TTT    EEE\n");
  163. output_string("BBBBBB     YYY      TTT    EEEEEEE\n\n");
  164. output_string("BYTEmark (tm) Native Mode Benchmark ver. 2 (3/95)\n");
  165.  
  166. /*
  167. ** See if the user wants all stats.  Output heading info
  168. ** if so.
  169. */
  170. if(global_allstats)
  171. {
  172.         output_string("========== ALL STATISTICS ==========\n");
  173.         time(&time_and_date);
  174.         loctime=localtime(&time_and_date);
  175.         sprintf(buffer,"**%s",asctime(loctime));
  176.         output_string(buffer);
  177.         sprintf(buffer,"**%s\n",sysname);
  178.         output_string(buffer);
  179.         sprintf(buffer,"**%s\n",compilername);
  180.         output_string(buffer);
  181.         sprintf(buffer,"**%s\n",compilerversion);
  182.         output_string(buffer);
  183.         sprintf(buffer,"**Sizeof: int:%u short:%u long:%u\n",
  184.                 (unsigned int)sizeof(int),
  185.                 (unsigned int)sizeof(short),
  186.                 (unsigned int)sizeof(long));
  187.         output_string(buffer);
  188.         output_string("====================================\n");
  189. }
  190.  
  191. /*
  192. ** Execute the tests.
  193. */
  194.  
  195. for(i=0;i<NUMTESTS;i++)
  196. {
  197.         if(tests_to_do[i])
  198.         {       sprintf(buffer,"%s:",ftestnames[i]);
  199.                 output_string(buffer);
  200.                 bench_with_confidence(i,
  201.                         &bmean,
  202.                         &bstdev,
  203.                         &bnumrun);
  204.                 sprintf(buffer,"  Iterations/sec.: %lf  Index: %lf\n",
  205.                         bmean,bmean/bindex[i]);
  206.                 output_string(buffer);
  207.                 /*
  208.                 ** Gather integer or FP indexes
  209.                 */
  210.                 if((i==4)||(i==8)||(i==9))
  211.                     /* FP index */
  212.                     fpindex=fpindex*(bmean/bindex[i]);
  213.                 else
  214.                     /* Integer index */
  215.                     intindex=intindex*(bmean/bindex[i]);
  216.                     
  217.                 if(global_allstats)
  218.                 {
  219.                         sprintf(buffer,"  Standard Deviation: %lf\n  Number of runs: %lu\n",
  220.                                 bstdev,bnumrun);
  221.                         output_string(buffer);
  222.                         show_stats(i);
  223.                 }
  224.         }
  225. }
  226. printf("...done...\n");
  227.  
  228. /*
  229. ** Output the total indexes
  230. */
  231. if(global_custrun==0)
  232. {
  233.     output_string("===========OVERALL============\n");
  234.     sprintf(buffer,"INTEGER INDEX: %lf\nFLOATING-POINT INDEX: %lf\n",pow(intindex,(double).142857),
  235.             pow(fpindex,(double).33333));
  236.     output_string(buffer);
  237.     output_string(" (90 MHz Dell Pentium = 1.00)\n");
  238.     output_string("==============================\n");
  239. }
  240.  
  241. exit(0);
  242. }
  243.  
  244. /**************
  245. ** parse_arg **
  246. ***************
  247. ** Given a pointer to a string, we assume that's an argument.
  248. ** Parse that argument and act accordingly.
  249. ** Return 0 if ok, else return -1.
  250. */
  251. static int parse_arg(char *argptr)
  252. {
  253. int i;          /* Index */
  254. FILE *cfile;    /* Command file identifier */
  255.  
  256. /*
  257. ** First character has got to be a hyphen.
  258. */
  259. if(*argptr++!='-') return(-1);
  260.  
  261. /*
  262. ** Convert the rest of the argument to upper case
  263. ** so there's little chance of confusion.
  264. */
  265. for(i=0;i<strlen(argptr);i++)
  266.         argptr[i]=(char)toupper((int)argptr[i]);
  267.  
  268. /*
  269. ** Next character picks the action.
  270. */
  271. switch(*argptr++)
  272. {
  273.         case '?':       return(-1);     /* Will display help */
  274.  
  275.         case 'C':                       /* Command file name */
  276.                 /*
  277.                 ** First try to open the file for reading.
  278.                 */
  279.                 cfile=fopen(argptr,"r");
  280.                 if(cfile==(FILE *)NULL)
  281.                 {       printf("**Error opening file: %s\n",argptr);
  282.                         return(-1);
  283.                 }
  284.                 read_comfile(cfile);    /* Read commands */
  285.                 fclose(cfile);
  286.                 break;
  287.         default:
  288.                 return(-1);
  289. }
  290. return(0);
  291. }
  292.  
  293. /*******************
  294. ** display_help() **
  295. ********************
  296. ** Display a help message showing argument requirements and such.
  297. ** Exit when you're done...I mean, REALLY exit.
  298. */
  299. static void display_help(char *progname)
  300. {
  301.         printf("Usage: %s [-c<FILE>]\n",progname);
  302.         printf(" -c = Input parameters thru command file <FILE>\n");
  303.         exit(0);
  304. }
  305.  
  306.  
  307. /*****************
  308. ** read_comfile **
  309. ******************
  310. ** Read the command file.  Set global parameters as
  311. ** specified.  This routine assumes that the command file
  312. ** is already open.
  313. */
  314. static void read_comfile(FILE *cfile)
  315. {
  316. char inbuf[40];
  317. char *eptr;             /* Offset to "=" sign */
  318. int i;                  /* Index */
  319.  
  320. /*
  321. ** Sit in a big loop, reading a line from the file at each
  322. ** pass.  Terminate on EOF.
  323. */
  324. while(fgets(inbuf,39,cfile)!=(char *)NULL)
  325. {
  326.         /* Overwrite the CR character */
  327.         if(strlen(inbuf)>0)
  328.                 inbuf[strlen(inbuf)-1]='\0';
  329.  
  330.         /*
  331.         ** Parse up to the "=" sign.  If we don't find an
  332.         ** "=", then flag an error.
  333.         */
  334.         if((eptr=strchr(inbuf,(int)'='))==(char *)NULL)
  335.         {       printf("**COMMAND FILE ERROR at LINE:\n %s\n",
  336.                         inbuf);
  337.                 goto skipswitch;        /* A GOTO!!!! */
  338.         }
  339.  
  340.         /*
  341.         ** Insert a null where the "=" was, then convert
  342.         ** the substring to uppercase.  That will enable
  343.         ** us to perform the match.
  344.         */
  345.         *eptr++='\0';
  346.         strtoupper((char *)&inbuf[0]);
  347.         i=MAXPARAM;                     
  348.         do {
  349.                 if(strcmp(inbuf,paramnames[i])==0)
  350.                         break;
  351.         } while(--i>=0);
  352.  
  353.         if(i<0)
  354.         {       printf("**COMMAND FILE ERROR -- UNKNOWN PARAM: %s",
  355.                         inbuf);
  356.                 goto skipswitch;
  357.         }
  358.  
  359.         /*
  360.         ** Advance eptr to the next field...which should be
  361.         ** the value assigned to the parameter.
  362.         */
  363.         switch(i)
  364.         {
  365.                 case PF_GMTICKS:        /* GLOBALMINTICKS */
  366.                         global_min_ticks=(ulong)atol(eptr);
  367.                         break;
  368.  
  369.                 case PF_MINSECONDS:     /* MINSECONDS */
  370.                         global_min_seconds=(ulong)atol(eptr);
  371.                         set_request_secs();
  372.                         break;
  373.  
  374.                 case PF_ALLSTATS:       /* ALLSTATS */
  375.                         global_allstats=getflag(eptr);
  376.                         break;
  377.  
  378.                 case PF_OUTFILE:        /* OUTFILE */
  379.                         strcpy(global_ofile_name,eptr);
  380.                         global_ofile=fopen(global_ofile_name,"a");
  381.                         /*
  382.                         ** Open the output file.
  383.                         */
  384.                         if(global_ofile==(FILE *)NULL)
  385.                         {       printf("**Error opening output file: %s\n",
  386.                                         global_ofile_name);
  387.                                 ErrorExit();
  388.                         }
  389.                         write_to_file=-1;
  390.                         break;
  391.  
  392.                 case PF_CUSTOMRUN:      /* CUSTOMRUN */
  393.                         global_custrun=getflag(eptr);
  394.                         for(i=0;i<NUMTESTS;i++)
  395.                                 tests_to_do[i]=1-global_custrun;
  396.                         break;
  397.  
  398.                 case PF_DONUM:          /* DONUMSORT */
  399.                         tests_to_do[TF_NUMSORT]=getflag(eptr);
  400.                         break;
  401.  
  402.                 case PF_NUMNUMA:        /* NUMNUMARRAYS */
  403.                         global_numsortstruct.numarrays=
  404.                                 (ushort)atoi(eptr);
  405.                         global_numsortstruct.adjust=1;
  406.                         break;
  407.  
  408.                 case PF_NUMASIZE:       /* NUMARRAYSIZE */
  409.                         global_numsortstruct.arraysize=
  410.                                 (ulong)atol(eptr);
  411.                         break;
  412.  
  413.                 case PF_NUMMINS:        /* NUMMINSECONDS */
  414.                         global_numsortstruct.request_secs=
  415.                                 (ulong)atol(eptr);
  416.                         break;
  417.  
  418.                 case PF_DOSTR:          /* DOSTRINGSORT */
  419.                         tests_to_do[TF_SSORT]=getflag(eptr);
  420.                         break;
  421.  
  422.                 case PF_STRASIZE:       /* STRARRAYSIZE */
  423.                         global_strsortstruct.arraysize=
  424.                                 (ulong)atol(eptr);
  425.                         break;
  426.  
  427.                 case PF_NUMSTRA:        /* NUMSTRARRAYS */
  428.                         global_strsortstruct.numarrays=
  429.                                 (ushort)atoi(eptr);
  430.                         global_strsortstruct.adjust=1;
  431.                         break;
  432.  
  433.                 case PF_STRMINS:        /* STRMINSECONDS */
  434.                         global_strsortstruct.request_secs=
  435.                                 (ulong)atol(eptr);
  436.                         break;
  437.  
  438.                 case PF_DOBITF: /* DOBITFIELD */
  439.                         tests_to_do[TF_BITOP]=getflag(eptr);
  440.                         break;
  441.  
  442.                 case PF_NUMBITOPS:      /* NUMBITOPS */
  443.                         global_bitopstruct.bitoparraysize=
  444.                                 (ulong)atol(eptr);
  445.                         global_bitopstruct.adjust=1;
  446.                         break;
  447.  
  448.                 case PF_BITFSIZE:       /* BITFIELDSIZE */
  449.                         global_bitopstruct.bitfieldarraysize=
  450.                                 (ulong)atol(eptr);
  451.                         break;
  452.  
  453.                 case PF_BITMINS:        /* BITMINSECONDS */
  454.                         global_bitopstruct.request_secs=
  455.                                 (ulong)atol(eptr);
  456.                         break;
  457.  
  458.                 case PF_DOEMF:          /* DOEMF */
  459.                         tests_to_do[TF_FPEMU]=getflag(eptr);
  460.                         break;
  461.  
  462.                 case PF_EMFASIZE:       /* EMFARRAYSIZE */
  463.                         global_emfloatstruct.arraysize=
  464.                                 (ulong)atol(eptr);
  465.                         break;
  466.  
  467.                 case PF_EMFLOOPS:       /* EMFLOOPS */
  468.                         global_emfloatstruct.loops=
  469.                                 (ulong)atol(eptr);
  470.                         break;
  471.  
  472.                 case PF_EMFMINS:        /* EMFMINSECOND */
  473.                         global_emfloatstruct.request_secs=
  474.                                 (ulong)atol(eptr);
  475.                         break;
  476.  
  477.                 case PF_DOFOUR: /* DOFOUR */
  478.                         tests_to_do[TF_FFPU]=getflag(eptr);
  479.                         break;
  480.  
  481.                 case PF_FOURASIZE:      /* FOURASIZE */
  482.                         global_fourierstruct.arraysize=
  483.                                 (ulong)atol(eptr);
  484.                         global_fourierstruct.adjust=1;
  485.                         break;
  486.  
  487.                 case PF_FOURMINS:       /* FOURMINSECONDS */
  488.                         global_fourierstruct.request_secs=
  489.                                 (ulong)atol(eptr);
  490.                         break;
  491.  
  492.                 case PF_DOASSIGN:       /* DOASSIGN */
  493.                         tests_to_do[TF_ASSIGN]=getflag(eptr);
  494.                         break;
  495.  
  496.                 case PF_AARRAYS:        /* ASSIGNARRAYS */
  497.                         global_assignstruct.numarrays=
  498.                                 (ulong)atol(eptr);
  499.                         break;
  500.  
  501.                 case PF_ASSIGNMINS:     /* ASSIGNMINSECONDS */
  502.                         global_assignstruct.request_secs=
  503.                                 (ulong)atol(eptr);
  504.                         break;
  505.  
  506.                 case PF_DOIDEA: /* DOIDEA */
  507.                         tests_to_do[TF_IDEA]=getflag(eptr);
  508.                         break;
  509.  
  510.                 case PF_IDEAASIZE:      /* IDEAARRAYSIZE */
  511.                         global_ideastruct.arraysize=
  512.                                 (ulong)atol(eptr);
  513.                         break;
  514.  
  515.                 case PF_IDEALOOPS:      /* IDEALOOPS */
  516.                         global_ideastruct.loops=
  517.                                 (ulong)atol(eptr);
  518.                         break;
  519.  
  520.                 case PF_IDEAMINS:       /* IDEAMINSECONDS */
  521.                         global_ideastruct.request_secs=
  522.                                 (ulong)atol(eptr);
  523.                         break;
  524.  
  525.                 case PF_DOHUFF: /* DOHUFF */
  526.                         tests_to_do[TF_HUFF]=getflag(eptr);
  527.                         break;
  528.  
  529.                 case PF_HUFFASIZE:      /* HUFFARRAYSIZE */
  530.                         global_huffstruct.arraysize=
  531.                                 (ulong)atol(eptr);
  532.                         break;
  533.  
  534.                 case PF_HUFFLOOPS:      /* HUFFLOOPS */
  535.                         global_huffstruct.loops=
  536.                                 (ulong)atol(eptr);
  537.                         global_huffstruct.adjust=1;
  538.                         break;
  539.  
  540.                 case PF_HUFFMINS:       /* HUFFMINSECONDS */
  541.                         global_huffstruct.request_secs=
  542.                                 (ulong)atol(eptr);
  543.                         break;
  544.  
  545.                 case PF_DONNET: /* DONNET */
  546.                         tests_to_do[TF_NNET]=getflag(eptr);
  547.                         break;
  548.                     
  549.                 case PF_NNETLOOPS:      /* NNETLOOPS */
  550.                         global_nnetstruct.loops=
  551.                                 (ulong)atol(eptr);
  552.                         global_nnetstruct.adjust=1;
  553.                         break;
  554.  
  555.                 case PF_NNETMINS:       /* NNETMINSECONDS */
  556.                         global_nnetstruct.request_secs=
  557.                                 (ulong)atol(eptr);
  558.                         break;
  559.  
  560.                 case PF_DOLU:           /* DOLU */
  561.                         tests_to_do[TF_LU]=getflag(eptr);
  562.                         break;
  563.  
  564.                 case PF_LUNARRAYS:      /* LUNUMARRAYS */
  565.                         global_lustruct.numarrays=
  566.                                 (ulong)atol(eptr);
  567.                         global_lustruct.adjust=1;
  568.                         break;
  569.  
  570.                 case PF_LUMINS: /* LUMINSECONDS */
  571.                         global_lustruct.request_secs=
  572.                                 (ulong)atol(eptr);
  573.                         break;
  574.         }
  575. skipswitch:
  576.         continue;
  577. }       /* End while */
  578.  
  579. return;
  580. }
  581.  
  582. /************
  583. ** getflag **
  584. *************
  585. ** Return 1 if cptr points to "T"; 0 otherwise.
  586. */
  587. static int getflag(char *cptr)
  588. {
  589.         if(toupper((int)*cptr)=='T') return(1);
  590. return(0);
  591. }
  592.  
  593. /***************
  594. ** strtoupper **
  595. ****************
  596. ** Convert's a string to upper case.  The string is presumed
  597. ** to consist only of alphabetic characters, and to be terminated
  598. ** with a null.
  599. */
  600. static void strtoupper(char *s)
  601. {
  602.  
  603. do {
  604. /*
  605. ** Oddly enough, the following line did not work under THINK C.
  606. ** So, I modified it....hmmmm. --RG
  607.         *s++=(char)toupper((int)*s);
  608. */
  609.         *s=(char)toupper((int)*s);
  610.         s++;
  611. } while(*s!=(char)'\0');
  612. return;
  613. }
  614.  
  615. /*********************
  616. ** set_request_secs **
  617. **********************
  618. ** Set everyone's "request_secs" entry to whatever
  619. ** value is in global_min_secs.  This is done
  620. ** at the beginning, and possibly later if the
  621. ** user redefines global_min_secs in the command file.
  622. */
  623. static void set_request_secs(void)
  624. {
  625.  
  626. global_numsortstruct.request_secs=global_min_seconds;
  627. global_strsortstruct.request_secs=global_min_seconds;
  628. global_bitopstruct.request_secs=global_min_seconds;
  629. global_emfloatstruct.request_secs=global_min_seconds;
  630. global_fourierstruct.request_secs=global_min_seconds;
  631. global_assignstruct.request_secs=global_min_seconds;
  632. global_ideastruct.request_secs=global_min_seconds;
  633. global_huffstruct.request_secs=global_min_seconds;
  634. global_nnetstruct.request_secs=global_min_seconds;
  635. global_lustruct.request_secs=global_min_seconds;
  636.  
  637. return;
  638. }
  639.  
  640.  
  641. /**************************
  642. ** bench_with_confidence **
  643. ***************************
  644. ** Given a benchmark id that indicates a function, this
  645. ** routine repeatedly calls that benchmark, seeking
  646. ** to collect enough scores to get 5 that meet the confidence
  647. ** criteria.  Return 0 if ok, -1 if failure.
  648. ** Returns mean ans std. deviation of results if successful.
  649. */
  650. static int bench_with_confidence(int fid,       /* Function id */
  651.         double *mean,                   /* Mean of scores */
  652.         double *stdev,                  /* Standard deviation */
  653.         ulong *numtries)                /* # of attempts */
  654. {
  655. double myscores[5];             /* Need at least 5 scores */
  656. double c_half_interval;         /* Confidence half interval */
  657. int i;                          /* Index */
  658. double newscore;                /* For improving confidence interval */
  659.  
  660.  
  661. /*
  662. ** Get first 5 scores.  Then begin confidence testing.
  663. */
  664. for (i=0;i<5;i++)
  665. {       (*funcpointer[fid])();
  666.         myscores[i]=getscore(fid);
  667. }
  668. *numtries=5;            /* Show 5 attempts */
  669.  
  670. /*
  671. ** The system allows a maximum of 10 tries before it gives
  672. ** up.  Since we've done 5 already, we'll allow 5 more.
  673. */
  674.  
  675. /*
  676. ** Enter loop to test for confidence criteria.
  677. */
  678. while(1)
  679. {
  680.         /*
  681.         ** Calculate confidence.
  682.         */
  683.         calc_confidence(myscores,
  684.                 &c_half_interval,
  685.                 mean,
  686.                 stdev);
  687.  
  688.         /*
  689.         ** Is half interval 5% or less of mean?
  690.         ** If so, we can go home.  Otherwise,
  691.         ** we have to continue.
  692.         */
  693.         if(c_half_interval/ (*mean) <= (double)0.05)
  694.                 break;
  695.  
  696.         /*
  697.         ** Go get a new score and see if it
  698.         ** improves existing scores.
  699.         */
  700.         do {
  701.                 if(*numtries==10)
  702.                         return(-1);
  703.                 (*funcpointer[fid])();
  704.                 *numtries+=1;
  705.                 newscore=getscore(fid);
  706.         } while(seek_confidence(myscores,&newscore,
  707.                 &c_half_interval,mean,stdev)==0);
  708. }
  709.  
  710. return(0);
  711. }
  712.  
  713. /********************
  714. ** seek_confidence **
  715. *********************
  716. ** Pass this routine an array of 5 scores PLUS a new score.
  717. ** This routine tries the new score in place of each of
  718. ** the other five scores to determine if the new score,
  719. ** when replacing one of the others, improves the confidence
  720. ** half-interval.
  721. ** Return 0 if failure.  Original 5 scores unchanged.
  722. ** Return -1 if success.  Also returns new half-interval,
  723. ** mean, and stand. dev.
  724. */
  725. static int seek_confidence( double scores[5],
  726.                 double *newscore,
  727.                 double *c_half_interval,
  728.                 double *smean,
  729.                 double *sdev)
  730. {
  731. double sdev_to_beat;    /* Original sdev to be beaten */
  732. double temp;            /* For doing a swap */
  733. int is_beaten;          /* Indicates original was beaten */
  734. int i;                  /* Index */
  735.  
  736. /*
  737. ** First calculate original standard deviation
  738. */
  739. calc_confidence(scores,c_half_interval,smean,sdev);
  740. sdev_to_beat=*sdev;
  741. is_beaten=-1;
  742.  
  743. /*
  744. ** Try to beat original score.  We'll come out of this
  745. ** loop with a flag.
  746. */
  747. for(i=0;i<5;i++)
  748. {
  749.         temp=scores[i];
  750.         scores[i]=*newscore;
  751.         calc_confidence(scores,c_half_interval,smean,sdev);
  752.         scores[i]=temp;
  753.         if(sdev_to_beat>*sdev)
  754.         {       is_beaten=i;
  755.                 sdev_to_beat=*sdev;
  756.         }
  757. }
  758.  
  759. if(is_beaten!=-1)
  760. {       scores[is_beaten]=*newscore;
  761.         return(-1);
  762. }
  763. return(0);
  764. }
  765.  
  766. /********************
  767. ** calc_confidence **
  768. *********************
  769. ** Given a set of 5 scores, calculate the confidence
  770. ** half-interval.  We'l also return the sample mean and sample
  771. ** standard deviation.
  772. ** NOTE: This routines presumes a confidence of 95% and
  773. ** a confidence coefficient of .95
  774. */
  775. static void calc_confidence( double scores[],    /* Array of scores */
  776.                 double *c_half_interval, /* Confidence half-int */
  777.                 double *smean,           /* Standard mean */
  778.                 double *sdev)            /* Sample stand dev */
  779. {
  780. int i;          /* Index */
  781. /*
  782. ** First calculate mean.
  783. */
  784. *smean=(scores[0]+scores[1]+scores[2]+scores[3]+scores[4])/
  785.         (double)5.0;
  786.  
  787. /*
  788. ** Get standard deviation - first get variance
  789. */
  790. *sdev=(double)0.0;
  791. for(i=0;i<5;i++)
  792. {       *sdev+=(scores[i]-(*smean))*(scores[i]-(*smean));
  793. }
  794. *sdev/=(double)4.0;
  795. *sdev=sqrt(*sdev)/sqrt(5.0);
  796.  
  797. /*
  798. ** Now calculate the confidence half-interval.
  799. ** For a confidence level of 95% our confidence coefficient
  800. ** gives us a multiplying factor of 2.776
  801. ** (The upper .025 quartile of a t distribution with 4 degrees
  802. ** of freedom.)
  803. */
  804. *c_half_interval=(double)2.776 * (*sdev);
  805. return;
  806. }
  807.  
  808. /*************
  809. ** getscore **
  810. **************
  811. ** Return the score for a particular benchmark.
  812. */
  813. static double getscore(int fid)
  814. {
  815.  
  816. /*
  817. ** Fid tells us the function.  This is really a matter of
  818. ** doing the proper coercion.
  819. */
  820. switch(fid)
  821. {
  822.         case TF_NUMSORT:
  823.                 return(global_numsortstruct.sortspersec);
  824.         case TF_SSORT:
  825.                 return(global_strsortstruct.sortspersec);
  826.         case TF_BITOP:
  827.                 return(global_bitopstruct.bitopspersec);
  828.         case TF_FPEMU:
  829.                 return(global_emfloatstruct.emflops);
  830.         case TF_FFPU:
  831.                 return(global_fourierstruct.fflops);
  832.         case TF_ASSIGN:
  833.                 return(global_assignstruct.iterspersec);
  834.         case TF_IDEA:
  835.                 return(global_ideastruct.iterspersec);
  836.         case TF_HUFF:
  837.                 return(global_huffstruct.iterspersec);
  838.         case TF_NNET:
  839.                 return(global_nnetstruct.iterspersec);
  840.         case TF_LU:
  841.                 return(global_lustruct.iterspersec);
  842. }
  843. return((double)0.0);
  844. }
  845.  
  846. /******************
  847. ** output_string **
  848. *******************
  849. ** Displays a string on the screen.  Also, if the flag
  850. ** write_to_file is set, outputs the string to the output file.
  851. ** Note, this routine presumes that you've included a carriage
  852. ** return at the end of the buffer.
  853. */
  854. static void output_string(char *buffer)
  855. {
  856.  
  857. printf("%s",buffer);
  858. if(write_to_file!=0)
  859.         fprintf(global_ofile,"%s",buffer);
  860. return;
  861. }
  862.  
  863. /***************
  864. ** show_stats **
  865. ****************
  866. ** This routine displays statistics for a particular benchmark.
  867. ** The benchmark is identified by its id.
  868. */
  869. static void show_stats (int bid)
  870. {
  871. char buffer[80];        /* Display buffer */
  872.  
  873. switch(bid)
  874. {
  875.         case TF_NUMSORT:                /* Numeric sort */
  876.                 sprintf(buffer,"  Number of arrays: %d\n",
  877.                         global_numsortstruct.numarrays);
  878.                 output_string(buffer);
  879.                 sprintf(buffer,"  Array size: %ld\n",
  880.                         global_numsortstruct.arraysize);
  881.                 output_string(buffer);
  882.                 break;
  883.  
  884.         case TF_SSORT:          /* String sort */
  885.                 sprintf(buffer,"  Number of arrays: %d\n",
  886.                         global_strsortstruct.numarrays);
  887.                 output_string(buffer);
  888.                 sprintf(buffer,"  Array size: %ld\n",
  889.                         global_strsortstruct.arraysize);
  890.                 output_string(buffer);
  891.                 break;
  892.  
  893.         case TF_BITOP:          /* Bitmap operation */
  894.                 sprintf(buffer,"  Operations array size: %ld\n",
  895.                         global_bitopstruct.bitoparraysize);
  896.                 output_string(buffer);
  897.                 sprintf(buffer,"  Bitfield array size: %ld\n",
  898.                         global_bitopstruct.bitfieldarraysize);
  899.                 output_string(buffer);
  900.                 break;
  901.  
  902.         case TF_FPEMU:          /* Floating-point emulation */
  903.                 sprintf(buffer,"  Number of loops: %lu\n",
  904.                         global_emfloatstruct.loops);
  905.                 output_string(buffer);
  906.                 sprintf(buffer,"  Array size: %lu\n",
  907.                         global_emfloatstruct.arraysize);
  908.                 output_string(buffer);
  909.                 break;
  910.  
  911.         case TF_FFPU:           /* Fourier test */
  912.                 sprintf(buffer,"  Number of coefficients: %lu\n",
  913.                         global_fourierstruct.arraysize);
  914.                 output_string(buffer);
  915.                 break;
  916.  
  917.         case TF_ASSIGN:
  918.                 sprintf(buffer,"  Number of arrays: %lu\n",
  919.                         global_assignstruct.numarrays);
  920.                 output_string(buffer);
  921.                 break;
  922.  
  923.         case TF_IDEA:
  924.                 sprintf(buffer,"  Array size: %lu\n",
  925.                         global_ideastruct.arraysize);
  926.                 output_string(buffer);
  927.                 sprintf(buffer," Number of loops: %lu\n",
  928.                         global_ideastruct.loops);
  929.                 output_string(buffer);
  930.                 break;
  931.  
  932.         case TF_HUFF:
  933.                 sprintf(buffer,"  Array size: %lu\n",
  934.                         global_huffstruct.arraysize);
  935.                 output_string(buffer);
  936.                 sprintf(buffer,"  Number of loops: %lu\n",
  937.                         global_huffstruct.loops);
  938.                 output_string(buffer);
  939.                 break;
  940.  
  941.         case TF_NNET:
  942.                 sprintf(buffer,"  Number of loops: %lu\n",
  943.                         global_nnetstruct.loops);
  944.                 output_string(buffer);
  945.                 break;
  946.  
  947.         case TF_LU:
  948.                 sprintf(buffer,"  Number of arrays: %lu\n",
  949.                         global_lustruct.numarrays);
  950.                 output_string(buffer);
  951.                 break;
  952. }
  953. return;
  954. }
  955.  
  956. /*
  957. ** Following code added for Mac stuff, so that we can emulate command
  958. ** lines.
  959. */
  960.  
  961. #ifdef MAC
  962.  
  963. /*****************
  964. ** UCommandLine **
  965. ******************
  966. ** Reads in a command line, and sets up argc and argv appropriately.
  967. ** Note that this routine uses gets() to read in the line.  This means
  968. ** you'd better not enter more than 128 characters on a command line, or
  969. ** things will overflow, and oh boy...
  970. */
  971. void UCommandLine(void)
  972. {
  973. printf("Enter command line\n:");
  974. gets((char *)Uargbuff);
  975. UParse();
  976. return;
  977. }
  978.  
  979. /***********
  980. ** UParse **
  981. ************
  982. ** Parse the pseudo command-line.  This code appeared as part of the
  983. ** Small-C library in Dr. Dobb's ToolBook of C.
  984. ** It expects the following globals:
  985. ** argc = arg count
  986. ** argv = Pointer to array of char pointers
  987. ** Uargbuff = Character array that holds the arguments.  Should be 129 bytes long.
  988. ** Udummy1 = This is a 2-byte buffer that holds a "*", and acts as the first
  989. **  argument in the argument list.  This maintains compatibility with other
  990. **  C's, though it does not provide access to the executable filename.
  991. ** This routine allows for up to 20 individual command-line arguments.
  992. ** Also note that this routine does NOT allow for redirection.
  993. */
  994. void UParse(void)
  995. {
  996. unsigned char *ptr;
  997.  
  998. argc=0;         /* Start arg count */
  999. Udummy[0]='*';  /* Set dummy first argument */
  1000. Udummy[1]='\0';
  1001. argv[argc++]=(char *)Udummy;
  1002.  
  1003. ptr=Uargbuff;           /* Start pointer */
  1004. while(*ptr)
  1005. {
  1006.         if(isspace(*ptr))
  1007.         {       ++ptr;
  1008.                 continue;
  1009.         }
  1010.         if(argc<20) argv[argc++]=(char *)ptr;
  1011.         ptr=UField(ptr);
  1012. }
  1013. return;
  1014. }
  1015. /***********
  1016. ** UField **
  1017. ************
  1018. ** Isolate the next command-line field.
  1019. */
  1020. unsigned char *UField(unsigned char *ptr)
  1021. {
  1022. while(*ptr)
  1023. {       if(isspace(*ptr))
  1024.         {       *ptr=(unsigned char)NULL;
  1025.                 return(++ptr);
  1026.         }
  1027.         ++ptr;
  1028. }
  1029. return(ptr);
  1030. }
  1031. #endif
  1032.